/**
 * Created by Administrator on 2017/6/13.
 */

let https = require('https');
let crypto = require('crypto');
let variable = require('../data/variable.js');
let gameData = require('../util/gameData.js');
let util = require('./util.js');
let rpc = require('./rpc.js');
let log = require('./log.js');
var queryString = require('querystring');
var request = require('request');  
var xml2jsparseString = require('xml2js').parseString; 

let weixinSDK = module.exports;

weixinSDK.refresh = function (code , cb) { 
    var appid = variable.weixin[variable.weixin.use].appId;
    var secret = variable.weixin[variable.weixin.use].appSecretKey; 
    var params = { 'grant_type':'authorization_code','appid':appid,'secret':secret,'code':code};
    requestGet('', '/sns/oauth2/access_token', params , cb); 
    // { "access_token":"ACCESS_TOKEN",
    // "expires_in":7200,
    // "refresh_token":"REFRESH_TOKEN",
    // "openid":"OPENID",
    // "scope":"SCOPE" }
    // {"errcode":40029,"errmsg":"invalid code"} 
};

weixinSDK.refresh_token = function (refresh_token,cb) {  
    var appid = variable.weixin[variable.weixin.use].appId;
    var secret = variable.weixin[variable.weixin.use].appSecretKey; 
    var params = { 'grant_type':'refresh_token','appid':appid,'secret':secret,'refresh_token':refresh_token};
    requestGet('', '/sns/oauth2/refresh_token', params , cb); 
//{ "access_token":"ACCESS_TOKEN",
// "expires_in":7200,
// "refresh_token":"REFRESH_TOKEN",
// "openid":"OPENID",
// "scope":"SCOPE" }
// {"errcode":40029,"errmsg":"invalid code"}
};

weixinSDK.self = function (access_token , openid , cb) {   
    requestGet(access_token, '/sns/userinfo', {'openid':openid,'lang':'zh_CN'} , cb); 
//{    "openid":" OPENID",
// " nickname": NICKNAME,
// "sex":"1",
// "province":"PROVINCE"
// "city":"CITY",
// "country":"COUNTRY",
// "headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
// "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
// "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
// }
// {"errcode":40003,"errmsg":" invalid openid "}
};

weixinSDK.auth = function (access_token, openid, cb) {
    requestGet(access_token, '/sns/auth', {'openid':openid} , cb); 
    // { "errcode":0,"errmsg":"ok"}
};

weixinSDK.share = function (hrefURL,ticket, cb) {

    var appid = variable.weixin[variable.weixin.use].appId;
    
    var configEnd = {}
    configEnd.jsapi_ticket = ticket; // ticket
    configEnd.timestamp = createTimestamp(); // 时间戳
    configEnd.nonceStr = createNonceStr(); // 随机数
    configEnd.url = hrefURL;

    var keys = Object.keys(configEnd);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (val, key) {
        if (configEnd[val]){
            newArgs[val.toLowerCase()] = configEnd[val];
        }   
    })  
    console.log(newArgs);
    var str = util.paramToUrl(newArgs);  
    configEnd.signature = sign(str); // 签名 
    configEnd.appId = appid;
    console.log(configEnd);
    
    cb && cb(configEnd); 
};

weixinSDK.ticket = function (uid,hrefURL,callback) {
    var appid = variable.weixin[variable.weixin.use].appId;
    var secret = variable.weixin[variable.weixin.use].appSecretKey; 
    var url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + appid + '&secret=' + secret;
    request(url, (error, response, body) => {
        if (response.statusCode && response.statusCode === 200) {
            body = JSON.parse(body);
            var configEnd = {} 
            var ticketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + body.access_token + '&type=jsapi';
            request(ticketUrl, function(err, response, content) {
                content = JSON.parse(content);
                if (content.errcode == 0) { 
                    if(uid){
                        let param = {};
                        param.uid = uid;
                        param.ticket = content.ticket;
                        param.expire = content.expires_in;  
                        rpc.dc.send('setTicket',param);
                    }   
                    configEnd.jsapi_ticket = content.ticket; // ticket
                    configEnd.timestamp = createTimestamp(); // 时间戳
                    configEnd.nonceStr = createNonceStr(); // 随机数
                    configEnd.url = hrefURL;
                    
                    var keys = Object.keys(configEnd);
                    keys = keys.sort();
                    var newArgs = {};
                    keys.forEach(function (val, key) {
                        if (configEnd[val]){
                            newArgs[val.toLowerCase()] = configEnd[val];
                        }   
                    })  
                    console.log(newArgs);
                    var str = util.paramToUrl(newArgs); 
                    configEnd.signature = sign(str); // 签名
                    configEnd.appId = appid 
                    console.log(configEnd);
                    callback && callback(configEnd); // 回调前端JS方法
                }else{
                    callback && callback({'code':101,'message':error});
                }
            });
        }else{
            callback && callback({'code':100,'message':error});
        }   
    });
    
    // requestGet(access_token, '/cgi-bin/ticket/getticket', {'type':'jsapi'} , cb);  

};

weixinSDK.request = function (api,param,cb) {
    requestGet(null, api , param , cb);  
};

/**
 * 微信支付的所有参数
 * @param req 请求的资源, 获取必要的数据
 * @returns {{appId: string, timeStamp: Number, nonceStr: *, package: string, signType: string, paySign: *}}
 */ 
weixinSDK.getOrder = function ( obj, cb) {  
    
    getBrandWCPayParams(obj, function (error, responseData) {
        if (error) {
            cb(error);
        } else {
            cb(null, responseData);
        }
    });     
};

weixinSDK.orderQuery = function(data,callback){ 
    var appid = variable.weixin[variable.weixin.use].appId;
    var mch_id = variable.weixin[variable.weixin.use].mchId;
    data.appid = appid;
    data.mch_id = mch_id;
    data.nonce_str = createNonceStr(); 
    data.sign = getSign(data);
    var url = 'https://api.mch.weixin.qq.com/pay/orderquery';
    request.post(url,data,(error, response, body) => {
        console.log(body);
        // 微信返回的数据为 xml 格式， 需要装换为 json 数据， 便于使用
        xml2jsparseString(body, {async:true}, function (error, result) {
            console.log(result);
            if (error==null) {
                callback && callback(null,result.xml);
            } else {
                callback && callback({'code':100,'message':error});
            }   
        }); 
    });
};  

weixinSDK.orderClose = function(data,callback){ 
    var appid = variable.weixin[variable.weixin.use].appId;
    var mch_id = variable.weixin[variable.weixin.use].mchId;
    data.appid = appid;
    data.mch_id = mch_id;
    data.nonce_str = createNonceStr(); 
    data.sign = getSign(data);
    var url = 'https://api.mch.weixin.qq.com/pay/closeorder';
    request(url,data,(error, response, body) => {
        if (response.statusCode && response.statusCode === 200) {
            body = JSON.parse(body);
            callback && callback(null,body);
        }else{
            callback && callback({'code':100,'message':error});
        }      
    }); 
};  

weixinSDK.payCallback = function (data) {
    console.log('weixinSDK.payCallback'); 
    data = data.xml; 
    console.log(data);
    if(data.return_code[0]=="SUCCESS"){
        var ordersId = data.out_trade_no[0];
        var transactionId = data.transaction_id[0];
        var sign = data.sign[0];
        rpc.dc.send('payCallback', JSON.stringify({'ordersId':ordersId,'transactionId':transactionId,'sign':sign}));
    }   
    return true;
};  

function requestGet(access_token, api, param, cb) { 
    let T = Math.floor(Date.now() / 1000).toString(); 
    let pathAdd = '';
    if (param) {
        pathAdd = '&' + util.paramToUrl(param);
    }   
    var host = variable.weixin[variable.weixin.use].host; 
    let opt = {
        hostname: host, 
        path: api + '?T=' + T + '&access_token=' + access_token + pathAdd,
        method: 'GET' 
    };  
    https.request(opt, function (res) {
        let result = '';
        res.on('data', function (data) {
            result += data;
        });
        res.on('end', function () {
            try {  
                let data = JSON.parse(result);
                cb(data);
            } catch (e) {
                cb({"code": 401, 'message': e.message});
            }
        });
    }).on('error', function (e) {
        cb({"code": 400, 'message': e.message});
    }).end();
}

/**
 * 获取微信统一下单参数
 */
function getUnifiedorderXmlParams(obj){      
    var body = '<xml> ' +
        '<appid>'+obj.appid+'</appid> ' +
        '<attach>'+obj.attach+'</attach> ' +
        '<body>'+obj.body+'</body> ' +
        '<mch_id>'+obj.mch_id+'</mch_id> ' +
        '<nonce_str>'+obj.nonce_str+'</nonce_str> ' +
        '<notify_url>'+obj.notify_url+'</notify_url>' +
        '<openid>'+obj.openid+'</openid> ' +
        '<out_trade_no>'+obj.out_trade_no+'</out_trade_no>'+
        '<spbill_create_ip>'+obj.spbill_create_ip+'</spbill_create_ip> ' +
        '<total_fee>'+obj.total_fee+'</total_fee> ' +
        '<trade_type>'+obj.trade_type+'</trade_type> ' +
        '<sign>'+obj.sign+'</sign> ' +
        '</xml>';
    console.log(body);
    return body;
}

/**
 * 获取微信统一下单的接口数据
 */
function getPrepayId(obj){   
    var appid = variable.weixin[variable.weixin.use].appId;
    var mchid = variable.weixin[variable.weixin.use].mchId; 
    var notify_url = variable.weixin.notify_url; 
    // 生成统一下单接口参数
    var UnifiedorderParams = {
        appid : appid,
        attach : obj.attach,
        body : obj.body,
        mch_id : mchid,
        nonce_str: createNonceStr(),
        notify_url : notify_url,// 微信付款后的回调地址
        openid : obj.openid,
        out_trade_no : obj.out_trade_no,//new Date().getTime(), //订单号
        spbill_create_ip : obj.spbill_create_ip,
        total_fee : obj.total_fee,
        trade_type : 'JSAPI', 
    };  
    // 返回 promise 对象
    return  new Promise(function (resolve, reject) { 
        console.log("Promise>>>>");
        // 获取 sign 参数
        UnifiedorderParams.sign = getSign(UnifiedorderParams);
        console.log(UnifiedorderParams); 
        var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        request.post({url : url, body:JSON.stringify(getUnifiedorderXmlParams(UnifiedorderParams))}, function (error, response, body) {
            console.log(body);
            var prepay_id = '';
            if (!error && response.statusCode == 200) { 
                // 微信返回的数据为 xml 格式， 需要装换为 json 数据， 便于使用
                xml2jsparseString(body, {async:true}, function (error, result) {
                    prepay_id = result.xml.prepay_id[0];
                    // 放回数组的第一个元素
                    resolve(prepay_id);
                });
            } else { 
                reject(body);
            }
        });
    })
}

/**
 * 获取微信支付的签名
 * @param payParams
 */
function getSign(signParams){ 
    //对参数按照key=value的格式，并按照参数名ASCII字典序排序生成字符串： 
    var wxpaykey = variable.weixin[variable.weixin.use].payKey;  
    var keys = Object.keys(signParams);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function (val, key) {
        if (signParams[val]){
            newArgs[val] = signParams[val];
        }
    })  
    var string = util.paramToUrl(newArgs)+'&key='+wxpaykey;
    // 生成签名
    return crypto.createHash('md5').update(queryString.unescape(string), 'utf8').digest("hex").toUpperCase();
}

/**
 * 微信支付的所有参数
 * @param req 请求的资源, 获取必要的数据
 * @returns {{appId: string, timeStamp: Number, nonceStr: *, package: string, signType: string, paySign: *}}
 */
function getBrandWCPayParams( obj, callback ){ 
    var appid = variable.weixin[variable.weixin.use].appId;
    var prepay_id_promise = getPrepayId(obj); 
    prepay_id_promise.then(function (prepay_id) {
        var prepay_id = prepay_id;
        var wcPayParams = {
            "appId" : appid,     //公众号名称，由商户传入
            "timeStamp" : parseInt(new Date().getTime() / 1000).toString(),         //时间戳，自1970年以来的秒数
            "nonceStr" : createNonceStr(), //随机串
            // 通过统一下单接口获取
            "package" : "prepay_id="+prepay_id,
            "signType" : "MD5",         //微信签名方式：
        };
        wcPayParams.paySign = getSign(wcPayParams); //微信支付签名
        console.log(wcPayParams);
        callback(null, wcPayParams);
    },function (error) {
        callback(error);
    });
}

/**
 * 获取随机的NonceStr
 */
function createNonceStr() {
    return Math.random().toString(36).substr(2, 15);
};

/**
 * 时间戳
 */
function createTimestamp() {
    return parseInt(new Date().getTime() / 1000).toString();
};

function sign(str){  
    //将上面三个字符串拼接成一个字符串再进行sha1加密
    var sha1 = require('crypto').createHash('sha1'); 
    sha1.update(str);
    return sha1.digest('hex');
} 